package xyz.wbsite.dbtool.javafx.po;

import com.fasterxml.jackson.annotation.JsonIgnore;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import xyz.wbsite.dbtool.javafx.annotation.Property;
import xyz.wbsite.dbtool.javafx.manger.ManagerFactory;
import xyz.wbsite.dbtool.javafx.manger.ProjectManager;
import xyz.wbsite.dbtool.javafx.tool.Tool;

import java.util.ArrayList;
import java.util.List;

public class Table {
    @JsonIgnore
    private Module dBhandle;

    public Table() {
    }

    public Table(String tableName) {
        setTableName(tableName);
    }

    public Table(String tableName, String tableComment) {
        setTableName(tableName);
        this.tableComment = tableComment;
    }

    @Property("tableName")
    private SimpleStringProperty tableName = new SimpleStringProperty();
    @Property("tableComment")
    private String tableComment;
    @Property("create")
    private boolean create = true;
    @Property("delete")
    private boolean delete = true;
    @Property("update")
    private boolean update = true;
    @Property("find")
    private boolean find = true;
    @Property("get")
    private boolean get = true;
    @Property("search")
    private boolean search = false;
    @Property("sys")
    private boolean sys = true;
    @Property("ajax")
    private boolean ajax = true;
    @Property("api")
    private boolean api = false;
    @Property("msvr")
    private boolean msvr = false;

    @Property("html")
    private boolean page = true;
    @Property("pageAdd")
    private boolean pageAdd = true;
    @Property("pageDel")
    private boolean pageDel = true;
    @Property("pageImp")
    private boolean pageImp = true;
    @Property("pageExp")
    private boolean pageExp = true;

    @Property("methods")
    private List<TableMethod> methods = new ArrayList<>();

    /**
     * 对象字段
     */
    private ObservableList<Field> fields = FXCollections.observableArrayList();

    public boolean has(String type) {
        for (Field field : fields) {
            if (field.getFieldType().equals(type) && !field.getIsSystem()) {
                return true;
            }
        }
        return false;
    }

    public String getImport() {
        StringBuilder sb = new StringBuilder("");
        if (has("Date")) {
            sb.append("import java.util.Date;\n");
        }
        if (has("BigDecimal")) {
            sb.append("import java.math.BigDecimal;\n");
        }

        return sb.toString();
    }

    public boolean putField(Field field) {
        fields.add(field);
        return true;
    }

    public boolean putFirstField(Field field) {
        fields.add(0, field);
        return true;
    }

    public boolean needMgr() {
        boolean need = create || delete || update || find || get || search;
        if (need) {
            return need;
        }
        for (TableMethod method : methods) {
            if (method.isSelected()) {
                return true;
            }
        }
        return false;
    }

    public String getCName() {
        return Tool.ABB2Abb(getTableName());
    }

    public String getFName() {
        return Tool.lineToFieldName(getTableName());
    }

    public String getLName() {
        return Tool.lineToLPoint(getTableName());
    }

    public String getTableName() {
        return tableName.get();
    }

    public SimpleStringProperty tableNameProperty() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName.set(tableName);
    }

    public String getTableComment() {
        return tableComment;
    }

    public void setTableComment(String tableComment) {
        this.tableComment = tableComment != null ? tableComment : "";
    }

    public ObservableList<Field> getFields() {
        return fields;
    }

    public Module getdBhandle() {
        return dBhandle;
    }

    public void setdBhandle(Module dBhandle) {
        this.dBhandle = dBhandle;
    }

    public boolean getCreate() {
        return create;
    }

    public void setCreate(boolean create) {
        this.create = create;
    }

    public boolean getDelete() {
        return delete;
    }

    public void setDelete(boolean delete) {
        this.delete = delete;
    }

    public boolean getUpdate() {
        return update;
    }

    public void setUpdate(boolean update) {
        this.update = update;
    }

    public boolean getFind() {
        return find;
    }

    public void setFind(boolean find) {
        this.find = find;
    }

    public boolean getGet() {
        return get;
    }

    public void setGet(boolean get) {
        this.get = get;
    }

    public boolean getSearch() {
        return search;
    }

    public void setSearch(boolean search) {
        this.search = search;
    }

    public boolean isPage() {
        return page;
    }

    public void setPage(boolean page) {
        this.page = page;
    }

    public boolean isAjax() {
        return ajax;
    }

    public void setAjax(boolean ajax) {
        this.ajax = ajax;
    }

    public boolean isPageAdd() {
        return pageAdd;
    }

    public void setPageAdd(boolean pageAdd) {
        this.pageAdd = pageAdd;
    }

    public boolean isPageDel() {
        return pageDel;
    }

    public void setPageDel(boolean pageDel) {
        this.pageDel = pageDel;
    }

    public boolean isPageImp() {
        return pageImp;
    }

    public void setPageImp(boolean pageImp) {
        this.pageImp = pageImp;
    }

    public boolean isPageExp() {
        return pageExp;
    }

    public void setPageExp(boolean pageExp) {
        this.pageExp = pageExp;
    }

    public boolean getSys() {
        return sys;
    }

    public void setSys(boolean sys) {
        this.sys = sys;
        ProjectManager projectManager = ManagerFactory.getProjectManager();
        if (projectManager != null) projectManager.checkSysFields(this);
    }

    public boolean getApi() {
        return api;
    }

    public void setApi(boolean api) {
        this.api = api;
    }

    public boolean getMsvr() {
        return msvr;
    }

    public void setMsvr(boolean msvr) {
        this.msvr = msvr;
    }

    public boolean hasPrimaryKey() {
        for (Field field : fields) {
            if (field.getIsPrimaryKey()) {
                return true;
            }
        }
        return false;
    }

    public List<Field> primaryKeyList() {
        ArrayList<Field> list = new ArrayList<>();
        for (Field field : this.fields) {
            if (field.getIsPrimaryKey()) {
                list.add(field);
            }
        }
        return list;
    }

    public List<Field> searchKeyList() {
        ArrayList<Field> list = new ArrayList<>();
        for (Field field : this.fields) {
            if (field.getIsSearch()) {
                list.add(field);
            }
        }
        return list;
    }

    public boolean hasSearchKey() {
        for (Field field : fields) {
            if (field.getIsSearch()) {
                return true;
            }
        }
        return false;
    }

    public List<TableMethod> getMethods() {
        return methods;
    }

    public void setMethods(List<TableMethod> methods) {
        this.methods = methods;
    }
}
